package checkers3d.presentation;

import checkers3d.logic.IBoardObject;
import checkers3d.logic.PlayingSurfacePosition;
import java.awt.Color;
import java.awt.Point;
import java.util.LinkedList;

/**
 * A visible GUI component that exists as a set of grid aligned IDrawables in a
 * PlayingSurfacePositon 2D array.
 *
 * @author Ruben Acuna
 */
public class RenderResourcePlayingSurface2D implements IRenderResource
{
    /**
     * Data containing contents of PlayingSurfacePosition array.
     */
    PlayingSurfacePosition[][] playingSurface;

    /**
     * Size of tiles in pixels.
     */
    int tileSize;
    
    /**
     * Reference to the object that is currently viewing the PlayingSurface.
     */
    private Object viewer;

    /**
     * Class consturctor that takes a PlayingSurfacePosition array and tile size
     * in pixels.
     * @param surface
     * @param tileSize
     */
    public RenderResourcePlayingSurface2D(PlayingSurfacePosition[][] surface,
                                          int tileSize)
    {
        this.playingSurface = surface;
        this.tileSize = tileSize;
    }

    /**
     * Returns a list of IBoardObjects of a tile at a given point.
     *
     * @param x The X location of the objects list on the RenderResource.
     * @param y The Y location of the objects list on the RenderResource.
     * @return
     */
    public LinkedList<IBoardObject> getSurfaceBoardObjects(int x, int y)
    {
        return playingSurface[x][y].getPositionObjects();
    }

    /**
     * Returns the overlay color of a tile at a given point. Returns null if
     * there is no overlay.
     *
     * @param x The X location of the overlay on the RenderResource.
     * @param y The Y location of the overlay on the RenderResource.
     * @return
     */
    public Color getSurfaceOverlayColor(int x, int y)
    {
        Color color = null; //default to null for NONE

        switch(playingSurface[x][y].getOverlay())
        {
            case MOVEABLE:
            case JUMPABLE:
            case WARPABLE:
            case SETUPABLE:
                color = Color.YELLOW;
                break;
            case SELECTED_PIECE:
            case FORCED_SELECTED:
                color = Color.GREEN;
                break;
        }

        return color;

    }

    /**
     * Returns the width of the PlayingSurface in tiles.
     * @return Width in tiles.
     * @return
     */
    public int getWidthTiles()
    {
        return playingSurface.length;
    }

    /**
     * Returns the height of the PlayingSurface in tiles.
     * @return Height in tiles.
     */
    public int getHeightTiles()
    {
        return playingSurface[0].length;
    }

    /**
     * Returns the size of the tiles used in drawing. Tiles are squares.
     * @return The size of the tiles in pixels.
     */
    public int getTileSize()
    {
        return tileSize;
    }

    /**
     * Returns true if the given point is drawn by the PlayingSurface2D, false
     * otherwise.
     *
     * @param  point A point relative to this object's draw location.
     * @return       Boolean indicating if the point is drawn.
     * @see IRenderResource
     */
    public boolean containsPoint(Point point)
    {
        if (point.x < playingSurface.length * tileSize
         && point.y < playingSurface[0].length * tileSize)
            return true;
        else
            return false;
    }

    /**
     * Returns the height of this RenderResourcePlayingSurface2D in pixels.
     *
     * @return Height in pixels.
     * @see IRenderResource
     */
    public int getHeight()
    {
        return playingSurface[0].length;
    }

    /**
     * Returns the width of this RenderResourcePlayingSurface2D in pixels.
     *
     * @return Width in pixels.
     * @see IRenderResource
     */
    public int getWidth()
    {
        return playingSurface.length;
    }

    /**
     * Resets the animation of this render resource.
     */
    public void reset()
    {
        //do nothing.
    }
    
    /**
     * Informs this IRenderResourcePlayingSurface2D that a given amount of time
     * in milliseconds has elapsed. Used for animation and time events.
     *
     * @param ms Milliseconds elapsed.
     * @see IRenderResource
     */
    public void tick(int ms)
    {
        //do nothing.
    }

    /**
     * Returns the object currently viewing the PlayingSurface.
     *
     * @return Object viewing the PlayingSurface.
     */
    public Object getViewer()
    {
        return viewer;
    }

    /**
     * Sets the object currently viewing the PlayingSurface.
     *
     * @param viewer Object viewing the PlayingSurface.
     */
    public void setViewer(Object viewer)
    {
        this.viewer = viewer;
    }

    /**
     * Returns a string representation of this RenderResourcePlayingSurface2D.
     * Includes the surface width, height, and tile size.
     * @return A string representation of this GUIPictureBox.
     */
    @Override
    public String toString()
    {
        return getClass().getName() + " - height: " + getHeightTiles()
                                    + " width: " + getWidthTiles()
                                    + " tilesize: " + getTileSize();
    }

    /**
     * Informs this render resource that a given amount of time in milliseconds
     * has elapsed. Used for animation and time events.
     *
     * @param ms Milliseconds elapsed.
     */
    @Override
    public IRenderResource clone()
    {
        RenderResourcePlayingSurface2D copy = new RenderResourcePlayingSurface2D(playingSurface.clone(), this.getTileSize());

        return copy;
    }
}